using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using XNAProject.Core;


namespace XNAProject.GameElements
{
    public class Ocean : Microsoft.Xna.Framework.DrawableGameComponent
    {
        Effect effectOcean;                                                                                 //porps

        Model ocean;

        Matrix[] oceanBones;

        Texture2D colorOceanMap;
        Texture2D normalOceanMap;
        Texture2D reflectOceanMap;

        string colorMapPath;
        string normalMapPath;
        string reflectionMapPath;
        string modelPath;
        string effectPath;
        string effectTechnique;

        public float Scale { get; set; }
        public Vector3 Rotation { get; set; }
        public Vector3 Translation { get; set; }
        public float Hue { get; set; }
        public Vector4 vLightDirection { get; set; }

        public Ocean(Game game, string EffectPath, string ModelPath, string EffectTechnique, string ColorMapPath, string NormalMapParh,
            string ReflectionMapPath, float Scale, Vector3 Rotation, Vector3 Translation, float Hue, Vector4 vLightDirection)
            : base(game)
        {
            effectPath = EffectPath;                                                                        //constructor
            modelPath = ModelPath;
            colorMapPath = ColorMapPath;
            normalMapPath = NormalMapParh;
            effectTechnique = EffectTechnique;
            reflectionMapPath = ReflectionMapPath;

            this.Scale = Scale;
            this.Rotation = Rotation;
            this.Translation = Translation;
            this.Hue = Hue;
            this.vLightDirection = vLightDirection;            
        }

        public override void Initialize()
        {
            effectOcean = Game.Content.Load<Effect>(effectPath);                                            //load stuff
                                                                                                            //why not in LoadContent() ?
            colorOceanMap = Game.Content.Load<Texture2D>(colorMapPath);
            normalOceanMap = Game.Content.Load<Texture2D>(normalMapPath);
            reflectOceanMap = Game.Content.Load<Texture2D>(reflectionMapPath);

            base.Initialize();
        }

        protected override void LoadContent()
        {
            ocean = Game.Content.Load<Model>(modelPath);
            oceanBones = new Matrix[ocean.Bones.Count];
            ocean.CopyAbsoluteBoneTransformsTo(oceanBones);

            base.LoadContent();
        }

        protected override void UnloadContent()
        {          
            base.UnloadContent();
        }

        public override void Update(GameTime gameTime)
        {            

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)                                                        //draw the ocean
        {                                                                                                   //bones, effects, blah blah
            XNAProjectCamera camera = (XNAProjectCamera)Game.Services.GetService(typeof(XNAProjectCamera));

            effectOcean.CurrentTechnique = effectOcean.Techniques[effectTechnique];

            camera.renderMatrix = Matrix.CreateScale(Scale) * Matrix.CreateRotationX(Rotation.X) * Matrix.CreateRotationY(Rotation.Y)
                * Matrix.CreateRotationZ(Rotation.Z) * Matrix.CreateTranslation(Translation);

            Game.GraphicsDevice.BlendState = BlendState.AlphaBlend;
            //Game.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
            //Game.GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;

            //foreach (EffectPass pass in effectOcean.CurrentTechnique.Passes)
            //{
                foreach (ModelMesh mesh in ocean.Meshes)
                {
                    //foreach (ModelMeshPart part in mesh.MeshParts)
                    //{
                    foreach (BasicEffect effect in mesh.Effects)
                    {
                        effect.EnableDefaultLighting();
                        effect.PreferPerPixelLighting = true;

                        effect.World =
                            Matrix.CreateFromYawPitchRoll(
                            Rotation.Y,
                            Rotation.X,
                            Rotation.Z) *

                            Matrix.CreateScale(Scale) *

                            Matrix.CreateTranslation(Translation);

                        effect.Projection = camera.Projection;
                        effect.View = camera.View;
                        //camera.worldMatrix = oceanBones[mesh.ParentBone.Index] * camera.renderMatrix;

                        //Vector4 vecEye = new Vector4(camera.Position.X, camera.Position.Y, camera.Position.Z, 0);

                        //Matrix worldInverse = Matrix.Invert(camera.worldMatrix);

                        //effectOcean.Parameters["matWorldViewProj"].SetValue(camera.worldMatrix * camera.View * camera.Projection);
                        //effectOcean.Parameters["matWorld"].SetValue(camera.worldMatrix);
                        //effectOcean.Parameters["vecEye"].SetValue(vecEye);
                        //effectOcean.Parameters["vecLightDir"].SetValue(vLightDirection);
                        //effectOcean.Parameters["ColorMap"].SetValue(colorOceanMap);
                        //effectOcean.Parameters["BumpMap"].SetValue(normalOceanMap);
                        //effectOcean.Parameters["EnvMap"].SetValue(reflectOceanMap);
                        //effectOcean.Parameters["time"].SetValue(camera.moveObject / 2);
                        //effectOcean.Parameters["A"].SetValue(Hue);
                        //effectOcean.Parameters["bSpecular"].SetValue(true);

                        //pass.Apply();

                        ////Game.GraphicsDevice.SetVertexBuffers( modelVertexBuffer, new VertexBufferBinding(instanceVertexBuffer, 0, 1));
                        ////Game.GraphicsDevice.Vertices[0].SetSource(part.VertexBuffer, part.VertexOffset, part.VertexStride);
                        //Game.GraphicsDevice.Indices = part.IndexBuffer;
                        //Game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0,
                        //    part.NumVertices, part.StartIndex, part.PrimitiveCount);
                    }
                    mesh.Draw();
                }
            //}

            Game.GraphicsDevice.BlendState = BlendState.NonPremultiplied;

            base.Draw(gameTime);
        }
    }
}